{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">作者 : Fernando Perez, Emmanuelle Gouillart, Gaël Varoquaux, Valentin Haenel\n",
    "\n",
    "# 1.1 为什么是Python？\n",
    "\n",
    "## 1.1.1 科学家的需求\n",
    "\n",
    "- 获得数据（模拟，实验控制）\n",
    "- 操作及处理数据\n",
    "- 可视化结果... 理解我们在做什么！\n",
    "- 沟通结果：生成报告或出版物的图片，写报告\n",
    "\n",
    "## 1.1.2 要求\n",
    "\n",
    "- 对于经典的数学方法及基本的方法，有丰富的现成工具：我们不希望重新编写程序去画出曲线、傅立叶变换或者拟合算法。不要重复发明轮子！\n",
    "- 易于学习：计算机科学不是我们的工作也不是我们的教育背景。我们想要在几分钟内画出曲线，平滑一个信号或者做傅立叶变换，\n",
    "- 可以方便的与合作者、学生、客户进行交流，代码可以存在于实验室或公司里面：代码的可读性应该像书一样。因此，这种语言应该包含尽可能少的语法符号或者不必要的常规规定，使来自数学或科学领域读者愉悦的理解这些代码。\n",
    "- 语言高效，执行快...但是不需要是非常快的代码，因为如果我们花费了太多的时间来写代码，非常快的代码也是无用的。\n",
    "- 一个单一的语言/环境做所有事，如果可能的话，避免每个新问题都要学习新软件\n",
    "\n",
    "## 1.1.3 现有的解决方案\n",
    "\n",
    "科学家用哪种解决方案进行工作？\n",
    "\n",
    "### 编译语言：C、C++、Fortran等。\n",
    "\n",
    "- 优势：\n",
    "    - 非常快。极度优化的编译器。对于大量的计算来说，很难比这些语言的性能更好。\n",
    "    - 一些非常优化的科学计算包。比如：BLAS（向量/矩阵操作）\n",
    "\n",
    "- 不足：\n",
    "    - 使用起来令人痛苦：开发过程中没有任何互动，强制编译步骤，啰嗦的语法（&, ::, }}, ; 等），手动内存管理（在C中非常棘手）。对于非计算机学家他们是**艰深的语言**。\n",
    "\n",
    "### 脚本语言：Matlab\n",
    "- 优势：\n",
    "    - 对不同的领域的多种算法都有非常的类库。执行很快，因为这些类库通常使用编译语言写的。\n",
    "    - 友好的开发环境：完善的、组织良好的帮助，整合的编辑器等\n",
    "    - 有商业支持\n",
    "\n",
    "- 不足：\n",
    "    - 基础语言非常欠缺，会限制高级用户\n",
    "    - 不是免费的\n",
    "    \n",
    "### 其他脚本语言：Scilab、Octave、Igor、R、IDL等。\n",
    "\n",
    "- 优势：\n",
    "    - 开源、免费，或者至少比Matlba便宜。\n",
    "    - 一些功能非常高级（R的统计，Igor的图形等。）\n",
    "\n",
    "- 不足：\n",
    "    - 比Matlab更少的可用算法，语言也并不更高级\n",
    "    - 一些软件更专注于一个领域。比如，Gnuplot或xmgrace画曲线。这些程序非常强大，但是他们只限定于一个单一用途，比如作图。\n",
    "\n",
    "### 那Python呢？\n",
    "\n",
    "- 优势：\n",
    "    - 非常丰富的科学计算包（尽管比Matlab少一些）\n",
    "    - 精心设计的语言，允许写出可读性非常好并且结构良好的代码：我们“按照我们所想去写代码”。\n",
    "    - 对于科学计算外的其他任务也有许多类库（网站服务器管理，串口接收等等。）\n",
    "    - 免费的开源软件，广泛传播，有一个充满活力的社区。\n",
    "\n",
    "- 不足：\n",
    "    - 不太友好的开发环境，比如与Matlab相比。（更加极客向）。\n",
    "    - 并不是在其他专业软件或工具箱中可以找到算法都可以找到\n",
    "\n",
    "# 1.2 Python科学计算的构成\n",
    "\n",
    "与Matlba，Scilab或者R不同，Python并没有预先绑定的一组科学计算模块。下面是可以组合起来获得科学计算环境的基础的组件。\n",
    "\n",
    "- **Python**，通用的现代计算语言\n",
    "    - Python语言：数据类型（字符string，整型int），流程控制，数据集合（列表list，字典dict），模式等等。\n",
    "    - 标准库及模块\n",
    "    - 用Pyhon写的大量专业模块及应用：网络协议、网站框架等...以及科学计算。\n",
    "    - 开发工具（自动测试，文档生成）\n",
    "\n",
    "- **IPython**, 高级的**Python Shell** [http://ipython.org/](http://ipython.org/)\n",
    "![ipython](http://scipy-lectures.github.io/_images/snapshot_ipython.png)\n",
    "\n",
    "- **Numpy** : 提供了强大数值数组对象以及程序去操作它们。[http://www.numpy.org/](http://www.numpy.org/)\n",
    "- **Scipy** : 高级的数据处理程序。优化、回归插值等[http://www.scipy.org/](http://www.scipy.org/)\n",
    "- **Matplotlib** : 2D可视化，“出版级”的图表[http://matplotlib.sourceforge.net/](http://matplotlib.sourceforge.net/)\n",
    "![Matplotlib](http://scipy-lectures.github.io/_images/random_c.jpg)\n",
    "\n",
    "- **Mayavi** : 3D可视化[http://code.enthought.com/projects/mayavi/](http://code.enthought.com/projects/mayavi/)\n",
    "![Mayavi](http://scipy-lectures.github.io/_images/example_surface_from_irregular_data.jpg)\n",
    "\n",
    "# 1.3 交互工作流：IPython和文本编辑器\n",
    "\n",
    "** 测试和理解算法的交互工作**：在这个部分我们描述一下用[IPython](http://ipython.org/)的交互工作流来方便的研究和理解算法。\n",
    "\n",
    "Python是一门通用语言。与其他的通用语言一样，没有一个绝对权威的工作环境，也不止一种方法使用它。尽管这对新人来说不太好找到适合自己的方式，但是，这使得Python被用于在网站服务器或嵌入设备中编写程序。\n",
    "\n",
    "> **本部分的参考文档**：\n",
    "\n",
    "> **IPython用户手册**：[http://ipython.org/ipython-doc/dev/index.html](http://ipython.org/ipython-doc/dev/index.html)\n",
    "\n",
    "## 1.3.1 命令行交互\n",
    "\n",
    "启动ipython:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world\n"
     ]
    }
   ],
   "source": [
    "print('Hello world')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在对象后使用？运算符获得帮助:\n",
    "```python\n",
    "In [2]: print\n",
    "Type:          builtin_function_or_method\n",
    "Base Class:    <type ’builtin_function_or_method’>\n",
    "String Form:   <built-in function print>\n",
    "Namespace:     Python builtin\n",
    "Docstring:\n",
    "    print(value, ..., sep=’ ’, end=’\\n’, file=sys.stdout)\n",
    "    Prints the values to a stream, or to sys.stdout by default.\n",
    "    Optional keyword arguments:\n",
    "    file: a file-like object (stream); defaults to the current sys.stdout.\n",
    "    sep:  string inserted between values, default a space.\n",
    "    end:  string appended after the last value, default a newline.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3.2 在编辑器中详尽描述算法\n",
    "\n",
    "在文本编辑器中，创建一个my_file.py文件。在EPD（[Enthought Python Distribution](https://www.enthought.com/products/epd/)）中，你可以从开始按钮使用*Scite*。在[Python(x,y)](https://code.google.com/p/pythonxy/)中, 你可以使用Spyder。在Ubuntu中, 如果你还没有最喜欢的编辑器，我们建议你安装[Stani’s Python editor](http://sourceforge.net/projects/spe/)。在这个文件中，输入如下行：\n",
    "```python\n",
    "s = 'Hello world'\n",
    "print(s)\n",
    "```\n",
    "\n",
    "现在，你可以在IPython中运行它，并研究产生的变量："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world\n"
     ]
    }
   ],
   "source": [
    "%run my_file.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello world'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Variable   Type    Data/Info\n",
      "----------------------------\n",
      "s          str     Hello world\n"
     ]
    }
   ],
   "source": [
    "%whos"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**从脚本到函数**\n",
    "\n",
    ">尽管仅使用脚本工作很诱人，即一个满是一个接一个命令的文件，但是要有计划的逐渐从脚本进化到一组函数：\n",
    "\n",
    ">- 脚本不可复用，函数可复用。\n",
    "\n",
    ">- 以函数的角度思考，有助于将问题拆分为小代码块。\n",
    "\n",
    "## 1.3.3 IPython提示与技巧\n",
    "\n",
    "IPython用户手册包含关于使用IPython的大量信息，但是，为了帮你你更快的入门，这里快速介绍三个有用的功能：*历史*，*魔法函数*，*别称*和*tab完成*。\n",
    "\n",
    "与Unix Shell相似，IPython支持命令历史。按上下在之前输入的命令间切换：\n",
    "```python\n",
    "In [1]: x = 10\n",
    "In [2]: <UP>\n",
    "In [2]: x = 10\n",
    "```\n",
    "\n",
    "IPython通过在命令前加*%*字符的前缀，支持所谓魔法函数。例如，前面部分的函数*run*和*whos*都是魔法函数。请注意*automagic*设置默认是启用，允许你忽略前面的*%*。因此，你可以只输入魔法函数仍然是有效的。\n",
    "\n",
    "其他有用的魔法函数：\n",
    "\n",
    "- **%cd** 改变当前目录"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/Users/cloga/Documents\n"
     ]
    }
   ],
   "source": [
    "cd .."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **%timeit** 允许你使用来自标准库中的timeit模块来记录执行短代码端的运行时间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000000 loops, best of 3: 26.7 ns per loop\n"
     ]
    }
   ],
   "source": [
    "timeit x = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **%cpaste** 允许你粘贴代码，特别是来自网站的代码，前面带有标准的Python提示符 (即 >>>) 或ipython提示符的代码(即 in [3])：\n",
    "```python\n",
    "In [5]: cpaste\n",
    "Pasting code; enter ’--’ alone on the line to stop or use Ctrl-D. :In [3]: timeit x = 10\n",
    ":--\n",
    "10000000 loops, best of 3: 85.9 ns per loop\n",
    "In [6]: cpaste\n",
    "Pasting code; enter ’--’ alone on the line to stop or use Ctrl-D. :>>> timeit x = 10\n",
    ":--\n",
    "10000000 loops, best of 3: 86 ns per loop\n",
    "```\n",
    "- **%debug** 允许你进入事后除错。也就是说，如果你想要运行的代码抛出了一个异常，使用**%debug**将在抛出异常的位置进入排错程序。\n",
    "\n",
    "```python\n",
    "In [7]: x === 10\n",
    "File \"<ipython-input-6-12fd421b5f28>\", line 1\n",
    "x === 10 ^\n",
    "  SyntaxError: invalid syntax\n",
    "In [8]: debug\n",
    "> /home/esc/anaconda/lib/python2.7/site-packages/IPython/core/compilerop.py(87)ast_parse()\n",
    "       86         and are passed to the built-in compile function.\"\"\"\n",
    "  ---> 87         return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)\n",
    "88\n",
    "  ipdb>locals()\n",
    "  {’source’: u’x === 10\\n’, ’symbol’: ’exec’, ’self’:\n",
    "  <IPython.core.compilerop.CachingCompiler instance at 0x2ad8ef0>,\n",
    "  ’filename’: ’<ipython-input-6-12fd421b5f28>’}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**IPython help**\n",
    "\n",
    ">- 内置的IPython手册可以通过*%quickref*魔法函数进入。\n",
    ">- 输入*%magic*会显示所有可用魔法函数的列表。\n",
    "\n",
    "而且IPython提供了大量的*别称*来模拟常见的UNIX命令行工具比如*ls*等于list files，*cp*等于copy files以及*rm*等于remove files。输入*alias*可以显示所有的别称的列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total number of aliases: 12\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[('cat', 'cat'),\n",
       " ('cp', 'cp'),\n",
       " ('ldir', 'ls -F -G -l %l | grep /$'),\n",
       " ('lf', 'ls -F -l -G %l | grep ^-'),\n",
       " ('lk', 'ls -F -l -G %l | grep ^l'),\n",
       " ('ll', 'ls -F -l -G'),\n",
       " ('ls', 'ls -F -G'),\n",
       " ('lx', 'ls -F -l -G %l | grep ^-..x'),\n",
       " ('mkdir', 'mkdir'),\n",
       " ('mv', 'mv'),\n",
       " ('rm', 'rm'),\n",
       " ('rmdir', 'rmdir')]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alias"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，提一下*tab完成*功能，我们从IPython手册引用它的描述：\n",
    "\n",
    ">Tab completion, especially for attributes, is a convenient way to explore the structure of any object you’re dealing with. Simply type object_name.<TAB> to view the object’s attributes. Besides Python objects and keywords, tab completion also works on file and directory names.\n",
    "\n",
    "```python\n",
    "In [1]: x = 10\n",
    "In [2]: x.<TAB>\n",
    "x.bit_length x.conjugate x.denominator x.imag x.numerator x.real\n",
    "In [3]: x.real.\n",
    "x.real.bit_length x.real.denominator x.real.numerator x.real.conjugate x.real.imag x.real.real\n",
    "In [4]: x.real.\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
